#pragma once
#include "config.hpp"

#include <chrono>
#include <cstddef>
#include <cstring>
#include <iostream>
#include <string>

class ScopedTimer {
public:
    explicit ScopedTimer(const char *name)
        : m_name(name), m_beg(std::chrono::high_resolution_clock::now()) {}
    ScopedTimer(const char *name, uint64_t &ns) : ScopedTimer(name) {
        m_ns = &ns;
    }
    ~ScopedTimer() {
        auto end = std::chrono::high_resolution_clock::now();
        auto dur
            = std::chrono::duration_cast<std::chrono::nanoseconds>(end - m_beg);
        if (m_ns) {
            *m_ns = dur.count();
        }

        size_t len = strlen(m_name);
        std::string space = get_space_str(len, 39);

        std::cout << m_name << " : " << space << dur.count() / ITERATIONS
                  << " ns\n";
    }

private:
    const char *m_name;
    std::chrono::time_point<std::chrono::high_resolution_clock> m_beg;
    uint64_t *m_ns = nullptr;
};
